package cn.wolfcode.wolf2w.business.service.impl;

import cn.wolfcode.wolf2w.business.api.RemoteDestinationService;
import cn.wolfcode.wolf2w.business.api.RemoteNoteService;
import cn.wolfcode.wolf2w.business.api.RemoteStrategyService;
import cn.wolfcode.wolf2w.business.api.domain.Destination;
import cn.wolfcode.wolf2w.business.api.domain.Note;
import cn.wolfcode.wolf2w.business.api.domain.Strategy;
import cn.wolfcode.wolf2w.business.query.SearchQuery;
import cn.wolfcode.wolf2w.business.service.ISearchService;
import cn.wolfcode.wolf2w.common.core.constant.SecurityConstants;
import cn.wolfcode.wolf2w.member.api.RemoteUserInfoService;
import cn.wolfcode.wolf2w.member.api.domain.UserInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class SearchServiceImpl implements ISearchService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private RemoteStrategyService remoteStrategyService;

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private RemoteNoteService remoteNoteService;

    @Autowired
    private RemoteDestinationService remoteDestinationService;

    @Override
    public <T> Page<T> searchHighLight(Class<?> elClazz, Class<T> Clazz, SearchQuery qo, String... fields) throws InvocationTargetException, IllegalAccessException {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withQuery(
                QueryBuilders.multiMatchQuery(qo.getKeyword(),fields)
        );
        //分页
        PageRequest pageRequest = PageRequest.of(qo.getCurrentPage()-1, qo.getPageSize());
        builder.withPageable(pageRequest);

        //设置数组
        HighlightBuilder.Field[] fs = new HighlightBuilder.Field[fields.length];
        for (int i = 0; i < fs.length; i++) {
            fs[i] = new HighlightBuilder.Field(fields[i])
                    .preTags("<span style='color:red'>")
                    .postTags("</span>");
        }

        //高亮条件
        builder.withHighlightFields(fs);

        //进行查询
        NativeSearchQuery build = builder.build();
        SearchHits<?> hits = elasticsearchRestTemplate.search(build, elClazz);
        long totalHits = hits.getTotalHits();
        List<T> list = new ArrayList<>();
        for (SearchHit<?> hit : hits) {
            //获取id，通过id到mysql中进行查询
            Long id = Long.valueOf(hit.getId());
            T t = null;
            if (Clazz == Strategy.class){
                //mysql中查询攻略,攻略的mysql的service,跨域查询,这里是mysql查询到的基础数据
                t = (T) remoteStrategyService.getOne(id, SecurityConstants.INNER).getData();
            }else if(Clazz == UserInfo.class){
                t = (T) remoteUserInfoService.getOne(id,SecurityConstants.INNER).getData();
            }else if(Clazz == Note.class){
                t = (T) remoteNoteService.getOne(id,SecurityConstants.INNER).getData();
            }else if(Clazz == Destination.class){
                t = (T) remoteDestinationService.getOne(id,SecurityConstants.INNER).getData();
            }
            Map<String, List<String>> highlightFields = hit.getHighlightFields();
            Set<String> keySet = highlightFields.keySet();
            for (String key : keySet) {
                //得到value数组
                List<String> highLightList = highlightFields.get(key);
                StringBuffer sb = new StringBuffer();
                for (String s : highLightList) {
                    sb.append(sb);
                }
                String value = sb.toString();
                //赋值完成
                BeanUtils.setProperty(t,key,value);


            }
            list.add(t);

        }
        return new PageImpl<T>(list,pageRequest,totalHits);
    }
}
